#pragma once
#include "ElementHidingCollection.h"
#include "SerializableRegex.h"
#include <vector>
#include <unordered_map>
#include <string>
#include <iostream>

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/string.hpp>
#include "unordered_map_serialization.h"
#include <memory>

using namespace std;

class CFilterList
{
public:
	CFilterList(void);
	~CFilterList(void);


	void InitializeFromAdblockPlusFiltersFile(string path);
	void InitializeFromAdblockPlusFiltersStream(istream& stream);

	std::unordered_map<wstring, CSerializableRegex>& GetFiltersWithShortcuts();
	std::vector<CSerializableRegex>& GetFiltersWithoutShourtcuts();

	std::shared_ptr<CElementHidingCollection> GetElementHidingCollection()
	{
		return _elementHidingCollection;
	}

private:

	//this object contains all element hiding rules and expose them
	//to other object (AdvertBlocker) that knows how to use block this rules
	//CElementHidingCollection _elementHidingCollection;
	std::shared_ptr<CElementHidingCollection> _elementHidingCollection;

	//===================//

	//standard rules
	std::unordered_map<wstring, CSerializableRegex> _filtersWithShortcuts;
	std::vector<CSerializableRegex> _filtersWithoutShourtcuts;
	//===================//


	const unsigned int SHORTCUTS_SIZE;

	bool CheckForElementHidingRuleAndSaveIt(const string &rule);
	bool CheckForElementHidingRulesWithoutDomain(const string& rule);
	bool CheckForElementHidingRulesWithDomain(const string& rule);


	bool IsRuleComment(const string& rule);
	void FixNewLines(string& rule);
	CSerializableRegex TransformAdblockFilterToRegularExpressions(const string &filter);
	void ChangeFilterCharactersToRegexSpecialCharacters(string& filter);
	void RemoveFilterBeginningEndingCharacters(string& filter, bool& matchedToBeginning, bool& matchedToEnding);
	void CreateShortcutsIfPossible(const string& line, const CSerializableRegex& filter);
	bool GetShortcutForFilter(const string& filter, wstring& shortcut);
	void RemoveCharactersForMatchinBeginningAndEndOfAddress(string& filter);

	bool MatchFiltersWithShortcuts(const wstring& srcElement);
	bool MatchFiltersWithoutShortcuts(const wstring& srcElement);

	//methods for serialization
	friend class boost::serialization::access;    
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
		ar & _filtersWithoutShourtcuts;
		ar & _filtersWithShortcuts;

		ar & (*_elementHidingCollection);
    }
};

